package com.ve.ext;

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.ve.c51.R;
import com.ve.clexer.CLanguage;
import com.ve.clexer.WordBuffer;
import com.ve.utils.DisplayUtils;
import com.ve.view.editor.Editor;
import com.ve.view.editor.out.CaretInterface;
import com.ve.view.listener.TextListener;
import com.ve.view.text.document.Document;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class AutoCompleteLayout implements TextListener {
    private static final String TAG = AutoCompleteLayout.class.getSimpleName();
    private String inputWord;
    private Context context;
    private Editor editor;
    private PopupWindow popupWindow;
    private AutoCompleteAdapter autoCompleteAdapter;
    private RecyclerView recyclerView;
    private List<String> words;
    private TextListener nullTextListener = new TextAdapter();

    public AutoCompleteLayout(Editor editor) {
        this.context = editor.getContext();
        this.editor = editor;
        editor.getOperator().setTextListener(this);
        View view = LayoutInflater.from(context).inflate(R.layout.layout_autocomplete, null);
        popupWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, false);
        recyclerView = view.findViewById(R.id.layout_autocomplete_list);
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
        words = new ArrayList<>();
        words.addAll(Arrays.asList(CLanguage.BASIC_KEYWORDS));
        words.addAll(Arrays.asList(CLanguage.BASIC_TYPE_NAMES));
        autoCompleteAdapter = new AutoCompleteAdapter(new ArrayList<>());
        autoCompleteAdapter.setOnItemClickListener((adapter, view1, position) -> {
            if (TextUtils.isEmpty(inputWord)) {
                return;
            }

            String item = (String) adapter.getItem(position);
            editor.getOperator().setTextListener(nullTextListener);
            editor.getTextInterface().paste(item.substring(inputWord.length(), item.length()));

            editor.getOperator().setTextListener(this);

            popupWindow.dismiss();

            inputWord = null;
        });
        recyclerView.setAdapter(autoCompleteAdapter);
    }


    @Override
    public void onNewLine(int caretPosition, int p) {
        popupWindow.dismiss();
        inputWord = null;
        int row = editor.getCaretInterface().getRow();
        if (row > 0) {
            Document document = editor.getTextInterface().getDocument();
            int pos = document.gainPositionOfLine(row - 1);
            int length = document.length();
            char c;
            int i = 0;
            do {
                c = document.charAt(pos + i);
                i++;
            } while (i < length && CLanguage.isWhitespace(c));

            char[] chars = new char[i - 1];
            Arrays.fill(chars, ' ');
            editor.getOperator().setTextListener(nullTextListener);
            editor.getTextInterface().paste(new String(chars));

            editor.getOperator().setTextListener(this);

        }

    }

    @Override
    public void onDelete(int caretPosition, int count) {
        prepare(caretPosition - count);
    }

    @Override
    public void onAdd(CharSequence text, int caretPosition, int count) {
        if (TextUtils.isEmpty(text) || (text.length() == 1 && WordBuffer.typeOfChar(text.charAt(0)) != WordBuffer.CHAR)) {
            popupWindow.update();
            popupWindow.dismiss();
            return;
        }

        prepare(caretPosition);

    }

    private void prepare(int caretPosition) {
        String findWord = findWord(caretPosition - 1);
        Log.d(TAG, "prepare: " + caretPosition + " " + findWord);
        if (TextUtils.isEmpty(findWord)) {
            popupWindow.dismiss();
            return;
        }
        List<String> data = filterBy(findWord);
        if (data.size() == 0) {
            popupWindow.dismiss();
            return;
        }
        autoCompleteAdapter.setNewData(data);
        autoCompleteAdapter.notifyDataSetChanged();
        this.inputWord = findWord;

        CaretInterface caret = editor.getCaretInterface();

        popupWindow.showAsDropDown(editor, caret.getX(), caret.getY());
        int height = DisplayUtils.dp2px(context, 100);
        popupWindow.update(editor, (int) (caret.getX()+editor.getDisplayInterface().spaceWidth()*1.5f), caret.getY()+height, DisplayUtils.dp2px(context,84), height);



    }

    private List<String> filterBy(String input) {
        List<String> list = new ArrayList<>();
        for (String word : words) {
            if (word.startsWith(input)) {
                list.add(word);
                Log.d(TAG, "filterBy: " + word);
            }
        }
        Collections.sort(list);

        return list;
    }

    private String findWord(int position) {
        Document document = editor.getTextInterface().getDocument();
        char[] chars = new char[128];
        int l = chars.length;

        for (int i = 0; i < chars.length; i++) {
            char c = document.charAt(position - i);
            if (WordBuffer.typeOfChar(c) == WordBuffer.CHAR) {
                chars[--l] = c;
            } else {
                return new String(chars, l, chars.length - l);
            }
        }

        return null;
    }

    private class AutoCompleteAdapter extends BaseQuickAdapter<String, BaseViewHolder> {


        public AutoCompleteAdapter(@Nullable List<String> data) {
            super(R.layout.item_complete, data);
        }

        @Override
        protected void convert(BaseViewHolder helper, String item) {
            helper.setText(R.id.item_complete_name, item);
        }
    }
}
